인스턴스가 빌드 과정에서 빌드가 정상적으로 되지않는 이슈

문제 발생 배경

배포환경의 NEXT.JS 빌드과정에서 Creating an optimized production build ... 에서 넘어가지 않는 이슈 발생

  ▲ Next.js 14.2.8
  - Environments: .env
  - Experiments (use with caution):
    · instrumentationHook

   Creating an optimized production build ...

문제 분석

Cloudwatch 확인결과 Cpu의 가용량이 100퍼를 찍으며 인스턴스가 다운되는 상황발생메모리 부족`으로 결론


해결 과정

  1. 서치결과 메모리의 부족때 쓸수있는 swap memory에 대한 정보를 찾게되었다.
스왑 메모리란, 실제 메모리 Ram이 가득 찼지만 더 많은 메모리가 필요할때 
디스코 공간을 이용하여 부족한 메모리를 대체할 수 있는 공간을 의미.

ssh 포트로 접근해 swap memory로 사용할 공간을 설정을 하였고

인스턴스가 다운되는 상황은 피했지만 자바스크립트의 힙 메모리가 부족하다는 내용과 함께 빌드에 실패 그래도 다운 되는 상황은 피했고 힙 메모리가 부족하다는 명령어로 변경 되었다.

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

  1. 힙메모리에 대한 글을 찾아보다가 available메모리가 부족해지면 swap 공간을 활용해서 메모리사용의 분배를 하지만 node에서 빌드할때 쓰는 엔진의 가용 메모리 용량이 한정되어있다는 정보를 알게됨. ( node에서 사용할 수 있는 최대 메모리가 512MIB 기본값으로 설정 )

export NODE_OPTIONS="--max-old-space-size=2048" 명령어를 실행해보기로 결정

여전히 똑같은 에러메세지와 함께 실패 하였다.


  1. 빌드때 자바스크립트의 힙 메모리가 부족하다는 경고문이 떳고 지금 상황에서 빌드상황때 메모리의 부족이 가장 중요한 이슈라고 생각했다

그렇다면 빌드를 하는 장소를 우분투 서버에서가 아닌 github action에서 실행을해보고 빌드된 파일을 우분투 서버로 보내보는건 어떨까?

github action에서 빌드후 scp 명령어를 통해 .next파일을 통째로! 전달하게 yml 파일을 수정해보기로 결정
30분 대기해보고 안되면 인스턴스에 용량 증축 후 작업해보기로 함

Pasted image 20240927113346.png

뭔가 너무 오래걸린다는걸 생각 분명 실행은 되는거같다.


  1. 최적화를 해볼까? 가장 쉽게 생각할수있는건 빌드 된 파일의 캐시를 이용하여 증축된 부분만 보낼수있나? -> 너무 어렵다
    그럼 파일의 용량을 낮추는게 목적이라면 단순 압축 파일을 보내도 될거같다.

Pasted image 20240927114118.png

Pasted image 20240927120128.png

보내졌다. 그렇지만 새로 메인 브랜치에 올린 상태가 배포 환경에게 적용 되는 시간이 자그마치 평균 17분 이상 소모 되었다.


  1. 마지막으로 파일을 더 빠른 속도로 전송하는 방법을 고민해보았습니다. 기존에는 파일을 원본 그대로 전송했지만, 이를 개선하기 위해 깃허브 액션에서 압축 후 전송하는 방식을 도입했습니다.

처음에는 큰 효과가 없었습니다. 하지만 다양한 압축 방식을 시도해본 결과, 일반적인 리눅스 압축 방식 대신 압축률이 더 높은 방식을 선택했습니다. 또한 서버 배포에 불필요한 파일들(빌드 최적화용 캐시 파일 등)을 전송 대상에서 제외했습니다. 이러한 최적화로 CI/CD 실행 시간을 17분에서 1분 30초~2분대로 단축할 수 있었습니다.


🛠️ 교훈 및 개선점

예상보다 많은 시간이 소요된 큰 이슈였지만, 혼자서 해결해낸 값진 경험이었습니다. 생소한 에러를 마주하고 해외 포럼을 뒤지며 정보를 수집하는 과정에서, 개발자로서 프로젝트에 가장 도움이 될 방향이 무엇일지, 주어진 시간 내에 해결할 수 있을지, 아니면 Vercel 배포로 전환할지 등 많은 고민을 했습니다.

이러한 문제 해결 과정을 통해 개발자로서의 역량을 한층 성장시킬 수 있었습니다.

앞으로의 개선점으로는 Docker를 도입하여 로컬 환경과 프로덕션 환경을 일치시키는 방안이 있다는 것을 알게 되었습니다.